using JGSY.CMS.LowCode.Platform.Domain.Entities;
using JGSY.CMS.LowCode.Platform.Domain.Enums;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Repositories
{
    public class WorkflowTaskRepository : Repository<WorkflowTask>, IWorkflowTaskRepository
    {
        public WorkflowTaskRepository(LowCodeDbContext context) : base(context)
        {
        }

    public override async Task<WorkflowTask> AddAsync(WorkflowTask entity)
        {
            return await base.AddAsync(entity);
        }

        public async Task<WorkflowTask?> AutoAssignTaskAsync(long instanceId, string taskType)
        {
            // 简单的自动分配逻辑：找到第一个可用的用户
            var availableUsers = await _context.Users
                .Where(x => x.Status == 1) // 1 = 活跃状态
                .Take(1)
                .ToListAsync();

            if (availableUsers.Any())
            {
                var task = new WorkflowTask
                {
                    InstanceId = instanceId,
                    TaskName = taskType,
                    NodeName = taskType,
                    AssigneeId = availableUsers.First().Id,
                    Status = WorkflowTaskStatus.Pending,
                    CreatedAt = DateTime.UtcNow,
                    DueDate = DateTime.UtcNow.AddDays(3) // 默认3天期限
                };

                await _context.WorkflowTasks.AddAsync(task);
                await _context.SaveChangesAsync();
                return task;
            }

            return null;
        }

        public async Task<bool> BatchAssignTasksAsync(List<long> taskIds, long assignedTo)
        {
            var tasks = await _context.WorkflowTasks
                .Where(x => taskIds.Contains(x.Id))
                .ToListAsync();

            foreach (var task in tasks)
            {
                task.AssigneeId = assignedTo;
                task.UpdatedAt = DateTime.UtcNow;
            }

            await _context.SaveChangesAsync();
            return true;
        }

    public override async Task<int> CountAsync()
        {
            return await base.CountAsync();
        }

    public override async Task<int> CountAsync(Expression<Func<WorkflowTask, bool>> predicate)
        {
            return await base.CountAsync(predicate);
        }

    public override async Task DeleteAsync(WorkflowTask entity)
        {
            await base.DeleteAsync(entity);
        }

    public override async Task DeleteAsync(object id)
        {
            await base.DeleteAsync(id);
        }

    public override async Task<bool> ExistsAsync(Expression<Func<WorkflowTask, bool>> predicate)
        {
            return await base.ExistsAsync(predicate);
        }

    public override async Task<List<WorkflowTask>> FindAsync(Expression<Func<WorkflowTask, bool>> predicate)
        {
            return await base.FindAsync(predicate);
        }

    public override async Task<WorkflowTask?> FindSingleAsync(Expression<Func<WorkflowTask, bool>> predicate)
        {
            return await base.FindSingleAsync(predicate);
        }

        public async Task<List<WorkflowTask>> GetByAssigneeAsync(long assignedTo)
        {
            return await _context.WorkflowTasks
                .Where(x => x.AssigneeId == assignedTo)
                .OrderByDescending(x => x.CreatedAt)
                .ToListAsync();
        }

    public override async Task<WorkflowTask?> GetByIdAsync(object id)
        {
            return await base.GetByIdAsync(id);
        }

        public async Task<List<WorkflowTask>> GetByInstanceIdAsync(long instanceId)
        {
            return await _context.WorkflowTasks
                .Where(x => x.InstanceId == instanceId)
                .OrderBy(x => x.CreatedAt)
                .ToListAsync();
        }

        public async Task<IEnumerable<WorkflowTask>> GetByStatusAsync(WorkflowTaskStatus status, int pageIndex = 1, int pageSize = 20)
        {
            return await _context.WorkflowTasks
                .Where(x => x.Status == status)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .OrderByDescending(x => x.CreatedAt)
                .ToListAsync();
        }

        public async Task<List<WorkflowTask>> GetOverdueTasksAsync()
        {
            var now = DateTime.UtcNow;
            return await _context.WorkflowTasks
                .Where(x => x.Status == WorkflowTaskStatus.Pending 
                          && x.DueDate.HasValue 
                          && x.DueDate < now)
                .OrderBy(x => x.DueDate)
                .ToListAsync();
        }

    public override async Task<(List<WorkflowTask> Items, int Total)> GetPagedAsync(int pageIndex, int pageSize, Expression<Func<WorkflowTask, bool>>? predicate = null)
        {
            return await base.GetPagedAsync(pageIndex, pageSize, predicate);
        }

        public async Task<List<WorkflowTask>> GetPendingTasksAsync(long assignedTo)
        {
            return await _context.WorkflowTasks
                .Where(x => x.AssigneeId == assignedTo && x.Status == WorkflowTaskStatus.Pending)
                .OrderBy(x => x.DueDate)
                .ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetTaskStatisticsAsync(long assignedTo)
        {
            var statistics = await _context.WorkflowTasks
                .Where(x => x.AssigneeId == assignedTo)
                .GroupBy(x => x.Status)
                .Select(g => new { Status = g.Key.ToString(), Count = g.Count() })
                .ToDictionaryAsync(x => x.Status, x => x.Count);

            return statistics;
        }

    public override async Task<int> SaveChangesAsync()
        {
            return await base.SaveChangesAsync();
        }

        async Task<List<WorkflowTask>> IRepository<WorkflowTask>.GetAllAsync()
        {
            return await base.GetAllAsync();
        }
    }
}
